package com.bigfans.searchservice.api;

import com.bigfans.framework.es.request.AggregationResult;
import com.bigfans.framework.model.FTSPageBean;
import com.bigfans.framework.model.PageContext;
import com.bigfans.framework.utils.CollectionUtils;
import com.bigfans.framework.utils.StringHelper;
import com.bigfans.framework.web.BaseController;
import com.bigfans.framework.web.RequestHolder;
import com.bigfans.framework.web.RestResponse;
import com.bigfans.searchservice.api.clients.CatalogServiceClient;
import com.bigfans.searchservice.api.request.HttpParams;
import com.bigfans.searchservice.model.*;
import com.bigfans.searchservice.model.vo.*;
import com.bigfans.searchservice.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 品牌搜索服务
 *
 * @author lichong
 */
@RestController
public class ProductSearchApi extends BaseController {

    @Autowired
    private ProductSearchService productSearchService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CatalogServiceClient catalogServiceClient;
    @Autowired
    private HotSearchService hotSearchService;

    private Logger logger = LoggerFactory.getLogger(ProductSearchApi.class);

    /**
     * @param keyword
     * @return
     */
    // /search?q=xxx&b=xxx&p=xxx_xxx&o=xxx
    // 格式:属性id_属性值id,属性id_属性值id
    // /search?params=1234_4321,222_333
    @GetMapping(value = "/search") //get方式不支持传递中文,需要进行转码
    public RestResponse search(
            @RequestParam(name = HttpParams.SearchFilter.KEYWORD, required = false) String keyword,
            @RequestParam(name = HttpParams.SearchFilter.CATEGORY, required = false) String catId,
            @RequestParam(name = HttpParams.SearchFilter.BRAND, required = false) String brandId,
            @RequestParam(name = HttpParams.SearchFilter.FILTER, required = false) String filters,
            @RequestParam(name = HttpParams.SearchFilter.PRICE, required = false) String priceRange,
            @RequestParam(name = HttpParams.SearchFilter.ORDER_BY, required = false) String orderBy,
            @RequestParam(name = HttpParams.SearchFilter.CURRENT_PAGE, required = false, defaultValue = "1") Integer cp
    ) throws Exception {
        PageContext.setCurrentPage(cp.longValue());
        PageContext.setPageSize(30L);
        // 1. 初始化参数
        ProductSearchRequest searchRequest = new ProductSearchRequest();
        searchRequest.setKeyword(keyword);
        searchRequest.setCategoryId(catId);
        searchRequest.setBrandId(brandId);
        if (StringHelper.isNotEmpty(filters)) {
            Map<String, String> attrMap = new HashMap<>();
            String[] filterArr = filters.split(",");
            for (String filter : filterArr) {
                String[] attrVal = filter.split("_");
                attrMap.put(attrVal[0], attrVal[1]);
            }
            searchRequest.setAttrs(attrMap);
        }
        if (StringHelper.isNotEmpty(priceRange)) {
            String[] split = priceRange.split("-");
            searchRequest.setMinPrice(split[0]);
            searchRequest.setMaxPrice(split[1]);
        }

        // 2. 执行搜索请求
        // TODO sort

        FTSPageBean<Product> productPage = productSearchService.searchProduct(searchRequest, PageContext.getStart().intValue(), PageContext.getPageSize().intValue());
        // 更新热门搜索
        hotSearchService.put(keyword);
        logger.info("keyword:" + keyword + ",resultCount:" + productPage.getTotalCount());
        // 创建页面filter选项
        // 未选择的filter
        List<SelectedFilter> selectedFilters = new ArrayList<>();
        // 已选择的filter
        List<UnSelectedFilter> unSelectedFilters = new ArrayList<>();
        this.buildFilter(searchRequest, productPage.getAggregationMap() , selectedFilters , unSelectedFilters);

        Map<String , Object> data = new HashMap<>();
        data.put("selectedFilters" , selectedFilters);
        data.put("unSelectedFilters" , unSelectedFilters);
        data.put("products" , productPage.getData());
        data.put("recordCount" , productPage.getTotalCount());
        data.put("pageCount" , productPage.getTotalPageCount());
        data.put("currentPage" , productPage.getCurrentPage());
        return RestResponse.ok(data);
    }

    private void buildFilter(ProductSearchRequest searchRequest, Map<String, List<AggregationResult>> aggMap , List<SelectedFilter> selectedFilters , List<UnSelectedFilter> unSelectedFilters) throws Exception {
        StringBuilder basicUrl = new StringBuilder(30);
        basicUrl.append("?").append(HttpParams.SearchFilter.KEYWORD).append("=").append(searchRequest.getKeyword());

        // 添加类别filter
        List<AggregationResult> catAggList = aggMap.get("category");
        this.buildCategoryFilter(searchRequest, basicUrl, catAggList, selectedFilters, unSelectedFilters);

        // 添加品牌filter
        List<AggregationResult> brandAggList = aggMap.get("brand");
        this.buildBrandFilter(searchRequest, basicUrl, brandAggList, selectedFilters, unSelectedFilters);

        // 添加商品属性filter
        List<AggregationResult> attrAggList = aggMap.get("attributes");
        this.buildAttributeFilter(searchRequest, basicUrl, attrAggList, selectedFilters, unSelectedFilters);

    }

    private void buildAttributeFilter(ProductSearchRequest searchRequest, StringBuilder basicUrl, List<AggregationResult> attrAggList, List<SelectedFilter> selectedFilters, List<UnSelectedFilter> unSelectedFilters) throws Exception {
        String selectedCategory = searchRequest.getCategoryId();
        String selectedBrand = searchRequest.getBrandId();
        Map<String, String> selectedAttrFilters = searchRequest.getAttrs();
        if (CollectionUtils.isNotEmpty(attrAggList)) {
            List<String> attrValueIdList = new ArrayList<>();
            for (AggregationResult attrAgg : attrAggList) {
                // name是attrValueId的值
                String attrValueId = attrAgg.getKey();
                attrValueIdList.add(attrValueId);
            }
            // 根据聚合的属性ID的结果,去数据库中查询出对应的数据
            CompletableFuture<List<AttributeValue>> future = catalogServiceClient.getAttributesByIdList(attrValueIdList);
            List<AttributeValue> attrVallist = future.get();
            Map<String, UnSelectedFilter> attrOptTemp = new HashMap<>();
            Map<String, SelectedFilter> selectedAttrOptTemp = new HashMap<>();
            for (AttributeValue attrVal : attrVallist) {
                // 创建已选择的filter
                String optId = attrVal.getOptionId();
                if (selectedAttrFilters.containsKey(optId)) {
                    String selectedValId = String.valueOf(selectedAttrFilters.get(optId));
                    if (!selectedValId.equals(attrVal.getId())) {
                        continue;
                    }
                    if (selectedAttrOptTemp.containsKey(attrVal.getOptionId())) {
                        continue;
                    }
                    FilterUrlBuilder attrUrlBuilder = new FilterUrlBuilder();
                    HashMap<String, String> attrCopy = new HashMap<>(selectedAttrFilters);
                    attrCopy.remove(attrVal.getOptionId());
                    attrUrlBuilder.attr(attrCopy);
                    attrUrlBuilder.cat(selectedCategory);
                    attrUrlBuilder.brand(selectedBrand);
                    attrUrlBuilder.url(basicUrl);
                    SelectedFilter filter = new SelectedFilter(attrVal.getOptionId(), attrVal.getOptionName() + ":" + attrVal.getValue(), attrUrlBuilder.build());
                    selectedAttrOptTemp.put(attrVal.getOptionId(), filter);
                } else { // 创建未选择的filter
                    FilterUrlBuilder attrUrlBuilder = new FilterUrlBuilder();
                    attrUrlBuilder.attr(selectedAttrFilters);
                    attrUrlBuilder.attr(attrVal.getOptionId(), attrVal.getId());
                    attrUrlBuilder.cat(selectedCategory);
                    attrUrlBuilder.brand(selectedBrand);
                    attrUrlBuilder.url(basicUrl);
                    SearchFilterItem sfo = new SearchFilterItem(attrVal.getOptionId(), attrVal.getValue(), attrUrlBuilder.build());
                    // 如果已经创建了filter,那么直接创建option
                    if (attrOptTemp.containsKey(attrVal.getOptionId())) {
                        attrOptTemp.get(attrVal.getOptionId()).addItem(sfo);
                    } else {
                        UnSelectedFilter filter = new UnSelectedFilter(attrVal.getOptionName());
                        filter.addItem(sfo);
                        attrOptTemp.put(attrVal.getOptionId(), filter);
                    }
                }
            }
            for (Map.Entry<String, UnSelectedFilter> entry : attrOptTemp.entrySet()) {
                unSelectedFilters.add(entry.getValue());
            }
            for (Map.Entry<String, SelectedFilter> entry : selectedAttrOptTemp.entrySet()) {
                selectedFilters.add(entry.getValue());
            }
        }
    }

    private void buildCategoryFilter(ProductSearchRequest searchRequest, StringBuilder basicUrl, List<AggregationResult> catAggList, List<SelectedFilter> selectedFilters, List<UnSelectedFilter> unSelectedFilters) throws Exception {
        String selectedCategory = searchRequest.getCategoryId();
        String selectedBrand = searchRequest.getBrandId();
        Map<String, String> selectedAttrFilters = searchRequest.getAttrs();
        if (StringHelper.isNotEmpty(selectedCategory)) {
            FilterUrlBuilder catUrlBuilder = new FilterUrlBuilder();
            catUrlBuilder.brand(selectedBrand);
            catUrlBuilder.attr(selectedAttrFilters);
            catUrlBuilder.url(basicUrl);
            // 创建已选择的filter
            Category cat = categoryService.getById(selectedCategory);
            SelectedFilter filter = new SelectedFilter(cat.getId(), "类别:" + cat.getName(), catUrlBuilder.build());
            selectedFilters.add(filter);
        } else {
            // 未选择的filter
            if (CollectionUtils.isNotEmpty(catAggList)) {
                UnSelectedFilter filter = new UnSelectedFilter("类别");
                for (AggregationResult aggregationResult : catAggList) {
                    String catId = aggregationResult.getKey();
                    Category cat = categoryService.getById(catId);
                    FilterUrlBuilder catUrlBuilder = new FilterUrlBuilder();
                    catUrlBuilder.brand(selectedBrand);
                    catUrlBuilder.attr(selectedAttrFilters);
                    catUrlBuilder.cat(cat.getId());
                    catUrlBuilder.url(basicUrl);
                    SearchFilterItem sfo = new SearchFilterItem(cat.getId(), cat.getName(), catUrlBuilder.build());
                    filter.addItem(sfo);
                }
                unSelectedFilters.add(filter);
            }
        }
    }

    private void buildBrandFilter(ProductSearchRequest searchRequest, StringBuilder basicUrl, List<AggregationResult> brandAggList, List<SelectedFilter> selectedFilters, List<UnSelectedFilter> unSelectedFilters) throws Exception {
        String selectedCategory = searchRequest.getCategoryId();
        String selectedBrand = searchRequest.getBrandId();
        HashMap<String, String> selectedAttrFilters = (HashMap<String, String>) RequestHolder.getAttribute("selectedFilters");
        if (StringHelper.isNotEmpty(selectedBrand)) {
            // 创建已选择的filter
            Brand brand = brandService.getById(selectedBrand);
            FilterUrlBuilder brandUrlBuilder = new FilterUrlBuilder();
            brandUrlBuilder.attr(selectedAttrFilters);
            brandUrlBuilder.cat(selectedCategory);
            brandUrlBuilder.url(basicUrl);
            SelectedFilter filter = new SelectedFilter(brand.getId(), "品牌:" + brand.getName(), brandUrlBuilder.build());
            selectedFilters.add(filter);
        } else {
            // 未选择的filter
            if (CollectionUtils.isNotEmpty(brandAggList)) {
                UnSelectedFilter filter = new UnSelectedFilter("品牌");
                for (AggregationResult aggregationResult : brandAggList) {
                    String brandId = aggregationResult.getKey();
                    Brand brand = brandService.getById(brandId);
                    FilterUrlBuilder brandUrlBuilder = new FilterUrlBuilder();
                    brandUrlBuilder.brand(brand.getId());
                    brandUrlBuilder.attr(selectedAttrFilters);
                    brandUrlBuilder.cat(selectedCategory);
                    brandUrlBuilder.url(basicUrl);
                    SearchFilterItem sfo = new SearchFilterItem(brand.getId(), brand.getName(), brandUrlBuilder.build());
                    filter.addItem(sfo);
                }
                unSelectedFilters.add(filter);
            }
        }
    }
}
